/*
### jQuery Google Maps Plugin v1.01 ###
* Home: http://www.mayzes.org/googlemaps.jquery.html
* Code: http://www.mayzes.org/js/jquery.googlemaps1.01.js
* Date: 2010-01-14 (Thursday, 14 Jan 2010)
* 
* Dual licensed under the MIT and GPL licenses.
*   http://www.gnu.org/licenses/gpl.html
*   http://www.opensource.org/licenses/mit-license.php
###
*/
jQuery.fn.googleMaps = function (options) {

    if (!window.GBrowserIsCompatible || !GBrowserIsCompatible()) {
        return this;
    }

    // Fill default values where not set by instantiation code
    var opts = $.extend({}, $.googleMaps.defaults, options);

    //$.fn.googleMaps.includeGoogle(opts.key, opts.sensor);
    return this.each(function () {
        // Create Map
        $.googleMaps.gMap = new GMap2(this, opts);
        $.googleMaps.mapsConfiguration(opts);
    });
};

$.googleMaps = {
    mapsConfiguration: function (opts) {
        // GEOCODE
        if (opts.geocode) {
            geocoder = new GClientGeocoder();
            geocoder.getLatLng(opts.geocode, function (center) {
                if (!center) {
                    alert(address + " not found");
                }
                else {
                    $.googleMaps.gMap.setCenter(center, opts.depth);
                    $.googleMaps.latitude = center.x;
                    $.googleMaps.longitude = center.y;
                }
            });
        }
        else {
            // Latitude & Longitude Center Point
            var center = $.googleMaps.mapLatLong(opts.latitude, opts.longitude);
            // Set the center of the Map with the new Center Point and Depth
            $.googleMaps.gMap.setCenter(center, opts.depth);
        }

        // POLYLINE
        if (opts.polyline)
        // Draw a PolyLine on the Map
            $.googleMaps.gMap.addOverlay($.googleMaps.mapPolyLine(opts.polyline));
        // GEODESIC 
        if (opts.geodesic) {
            $.googleMaps.mapGeoDesic(opts.geodesic);
        }
        // PAN
        if (opts.pan) {
            // Set Default Options
            opts.pan = $.googleMaps.mapPanOptions(opts.pan);
            // Pan the Map
            window.setTimeout(function () {
                $.googleMaps.gMap.panTo($.googleMaps.mapLatLong(opts.pan.panLatitude, opts.pan.panLongitude));
            }, opts.pan.timeout);
        }

        // LAYER
        if (opts.layer)
        // Set the Custom Layer
            $.googleMaps.gMap.addOverlay(new GLayer(opts.layer));

        // MARKERS
        if (opts.markers)
            $.googleMaps.mapMarkers(center, opts.markers);

        // CONTROLS
        if (opts.controls.type || opts.controls.zoom || opts.controls.mapType) {
            $.googleMaps.mapControls(opts.controls);
        }
        else {
            if (!opts.controls.hide)
                $.googleMaps.gMap.setUIToDefault();
        }

        // SCROLL
        if (opts.scroll)
            $.googleMaps.gMap.enableScrollWheelZoom();
        else if (!opts.scroll)
            $.googleMaps.gMap.disableScrollWheelZoom();

        // LOCAL SEARCH
        if (opts.controls.localSearch)
            $.googleMaps.gMap.enableGoogleBar();
        else
            $.googleMaps.gMap.disableGoogleBar();

        // FEED (RSS/KML)
        if (opts.feed)
            $.googleMaps.gMap.addOverlay(new GGeoXml(opts.feed));

        // TRAFFIC INFO
        if (opts.trafficInfo) {
            var trafficOptions = { incidents: true };
            trafficInfo = new GTrafficOverlay(trafficOptions);
            $.googleMaps.gMap.addOverlay(trafficInfo);
        }

        // DIRECTIONS
        if (opts.directions) {
            $.googleMaps.directions = new GDirections($.googleMaps.gMap, opts.directions.panel);
            $.googleMaps.directions.load(opts.directions.route);
        }

        if (opts.streetViewOverlay) {
            svOverlay = new GStreetviewOverlay();
            $.googleMaps.gMap.addOverlay(svOverlay);
        }
    },
    mapGeoDesic: function (options) {
        // Default GeoDesic Options
        geoDesicDefaults = {
            startLatitude: 37.4419,
            startLongitude: -122.1419,
            endLatitude: 37.4519,
            endLongitude: -122.1519,
            color: '#ff0000',
            pixels: 2,
            opacity: 10
        }
        // Merge the User & Default Options
        options = $.extend({}, geoDesicDefaults, options);
        var polyOptions = { geodesic: true };
        var polyline = new GPolyline([
			new GLatLng(options.startLatitude, options.startLongitude),
			new GLatLng(options.endLatitude, options.endLongitude)],
			options.color, options.pixels, options.opacity, polyOptions
		);
        $.googleMaps.gMap.addOverlay(polyline);
    },
    localSearchControl: function (options) {
        var controlLocation = $.googleMaps.mapControlsLocation(options.location);
        $.googleMaps.gMap.addControl(new $.googleMaps.gMap.LocalSearch(), new GControlPosition(controlLocation, new GSize(options.x, options.y)));
    },
    getLatitude: function () {
        return $.googleMaps.latitude;
    },
    getLongitude: function () {
        return $.googleMaps.longitude;
    },
    directions: {},
    latitude: '',
    longitude: '',
    latlong: {},
    maps: {},
    marker: {},
    gMap: {},
    defaults: {
        // Default Map Options
        latitude: 37.4419,
        longitude: -122.1419,
        depth: 13,
        scroll: true,
        trafficInfo: false,
        streetViewOverlay: false,
        controls: {
            hide: false,
            localSearch: false
        },
        layer: null
    },
    mapPolyLine: function (options) {
        // Default PolyLine Options
        polylineDefaults = {
            startLatitude: 37.4419,
            startLongitude: -122.1419,
            endLatitude: 37.4519,
            endLongitude: -122.1519,
            color: '#ff0000',
            pixels: 2
        }
        // Merge the User & Default Options
        options = $.extend({}, polylineDefaults, options);
        //Return the New Polyline
        return new GPolyline([
			$.googleMaps.mapLatLong(options.startLatitude, options.startLongitude),
			$.googleMaps.mapLatLong(options.endLatitude, options.endLongitude)],
			options.color,
			options.pixels
		);
    },
    mapLatLong: function (latitude, longitude) {
        // Returns Latitude & Longitude Center Point
        return new GLatLng(latitude, longitude);
    },
    mapPanOptions: function (options) {
        // Returns Panning Options
        var panDefaults = {
            panLatitude: 37.4569,
            panLongitude: -122.1569,
            timeout: 0
        }
        return options = $.extend({}, panDefaults, options);
    },
    mapMarkersOptions: function (icon) {
        //Define an icon
        var gIcon = new GIcon(G_DEFAULT_ICON);
        if (icon.image)
        // Define Icons Image
            gIcon.image = icon.image;
        if (icon.shadow)
        // Define Icons Shadow
            gIcon.shadow = icon.shadow;
        if (icon.iconSize)
        // Define Icons Size
            gIcon.iconSize = new GSize(icon.iconSize);
        if (icon.shadowSize)
        // Define Icons Shadow Size
            gIcon.shadowSize = new GSize(icon.shadowSize);
        if (icon.iconAnchor)
        // Define Icons Anchor
            gIcon.iconAnchor = new GPoint(icon.iconAnchor);
        if (icon.infoWindowAnchor)
        // Define Icons Info Window Anchor
            gIcon.infoWindowAnchor = new GPoint(icon.infoWindowAnchor);
        if (icon.dragCrossImage)
        // Define Drag Cross Icon Image
            gIcon.dragCrossImage = icon.dragCrossImage;
        if (icon.dragCrossSize)
        // Define Drag Cross Icon Size
            gIcon.dragCrossSize = new GSize(icon.dragCrossSize);
        if (icon.dragCrossAnchor)
        // Define Drag Cross Icon Anchor
            gIcon.dragCrossAnchor = new GPoint(icon.dragCrossAnchor);
        if (icon.maxHeight)
        // Define Icons Max Height
            gIcon.maxHeight = icon.maxHeight;
        if (icon.PrintImage)
        // Define Print Image
            gIcon.PrintImage = icon.PrintImage;
        if (icon.mozPrintImage)
        // Define Moz Print Image
            gIcon.mozPrintImage = icon.mozPrintImage;
        if (icon.PrintShadow)
        // Define Print Shadow
            gIcon.PrintShadow = icon.PrintShadow;
        if (icon.transparent)
        // Define Transparent
            gIcon.transparent = icon.transparent;
        return gIcon;
    },
    mapMarkers: function (center, markers) {
        if (typeof (markers.length) == 'undefined')
        // One marker only. Parse it into an array for consistency.
            markers = [markers];

        var j = 0;
        for (i = 0; i < markers.length; i++) {
            var gIcon = null;
            if (markers[i].icon) {
                gIcon = $.googleMaps.mapMarkersOptions(markers[i].icon);
            }

            if (markers[i].geocode) {
                var geocoder = new GClientGeocoder();
                geocoder.getLatLng(markers[i].geocode, function (center) {
                    if (!center)
                        alert(address + " not found");
                    else
                        $.googleMaps.marker[i] = new GMarker(center, { draggable: markers[i].draggable, icon: gIcon });
                });
            }
            else if (markers[i].latitude && markers[i].longitude) {
                // Latitude & Longitude Center Point
                center = $.googleMaps.mapLatLong(markers[i].latitude, markers[i].longitude);
                $.googleMaps.marker[i] = new GMarker(center, { draggable: markers[i].draggable, icon: gIcon });
            }
            $.googleMaps.gMap.addOverlay($.googleMaps.marker[i]);
            if (markers[i].info) {
                // Hide Div Layer With Info Window HTML
                $(markers[i].info.layer).hide();
                // Marker Div Layer Exists
                if (markers[i].info.popup)
                // Map Marker Shows an Info Box on Load
                    $.googleMaps.marker[i].openInfoWindowHtml($(markers[i].info.layer).html());
                else
                    $.googleMaps.marker[i].bindInfoWindowHtml($(markers[i].info.layer).html().toString());
            }
        }
    },
    mapControlsLocation: function (location) {
        switch (location) {
            case 'G_ANCHOR_TOP_RIGHT':
                return G_ANCHOR_TOP_RIGHT;
                break;
            case 'G_ANCHOR_BOTTOM_RIGHT':
                return G_ANCHOR_BOTTOM_RIGHT;
                break;
            case 'G_ANCHOR_TOP_LEFT':
                return G_ANCHOR_TOP_LEFT;
                break;
            case 'G_ANCHOR_BOTTOM_LEFT':
                return G_ANCHOR_BOTTOM_LEFT;
                break;
        }
        return;
    },
    mapControl: function (control) {
        switch (control) {
            case 'GLargeMapControl3D':
                return new GLargeMapControl3D();
                break;
            case 'GLargeMapControl':
                return new GLargeMapControl();
                break;
            case 'GSmallMapControl':
                return new GSmallMapControl();
                break;
            case 'GSmallZoomControl3D':
                return new GSmallZoomControl3D();
                break;
            case 'GSmallZoomControl':
                return new GSmallZoomControl();
                break;
            case 'GScaleControl':
                return new GScaleControl();
                break;
            case 'GMapTypeControl':
                return new GMapTypeControl();
                break;
            case 'GHierarchicalMapTypeControl':
                return new GHierarchicalMapTypeControl();
                break;
            case 'GOverviewMapControl':
                return new GOverviewMapControl();
                break;
            case 'GNavLabelControl':
                return new GNavLabelControl();
                break;
        }
        return;
    },
    mapTypeControl: function (type) {
        switch (type) {
            case 'G_NORMAL_MAP':
                return G_NORMAL_MAP;
                break;
            case 'G_SATELLITE_MAP':
                return G_SATELLITE_MAP;
                break;
            case 'G_HYBRID_MAP':
                return G_HYBRID_MAP;
                break;
        }
        return;
    },
    mapControls: function (options) {
        // Default Controls Options
        controlsDefaults = {
            type: {
                location: 'G_ANCHOR_TOP_RIGHT',
                x: 10,
                y: 10,
                control: 'GMapTypeControl'
            },
            zoom: {
                location: 'G_ANCHOR_TOP_LEFT',
                x: 10,
                y: 10,
                control: 'GLargeMapControl3D'
            }
        };
        // Merge the User & Default Options
        options = $.extend({}, controlsDefaults, options);
        options.type = $.extend({}, controlsDefaults.type, options.type);
        options.zoom = $.extend({}, controlsDefaults.zoom, options.zoom);

        if (options.type) {
            var controlLocation = $.googleMaps.mapControlsLocation(options.type.location);
            var controlPosition = new GControlPosition(controlLocation, new GSize(options.type.x, options.type.y));
            $.googleMaps.gMap.addControl($.googleMaps.mapControl(options.type.control), controlPosition);
        }
        if (options.zoom) {
            var controlLocation = $.googleMaps.mapControlsLocation(options.zoom.location);
            var controlPosition = new GControlPosition(controlLocation, new GSize(options.zoom.x, options.zoom.y))
            $.googleMaps.gMap.addControl($.googleMaps.mapControl(options.zoom.control), controlPosition);
        }
        if (options.mapType) {
            if (options.mapType.length >= 1) {
                for (i = 0; i < options.mapType.length; i++) {
                    if (options.mapType[i].remove)
                        $.googleMaps.gMap.removeMapType($.googleMaps.mapTypeControl(options.mapType[i].remove));
                    if (options.mapType[i].add)
                        $.googleMaps.gMap.addMapType($.googleMaps.mapTypeControl(options.mapType[i].add));
                }
            }
            else {
                if (options.mapType.add)
                    $.googleMaps.gMap.addMapType($.googleMaps.mapTypeControl(options.mapType.add));
                if (options.mapType.remove)
                    $.googleMaps.gMap.removeMapType($.googleMaps.mapTypeControl(options.mapType.remove));
            }
        }
    },
    geoCode: function (options) {
        geocoder = new GClientGeocoder();

        geocoder.getLatLng(options.address, function (point) {
            if (!point)
                alert(address + " not found");
            else
                $.googleMaps.gMap.setCenter(point, options.depth);
        });
    }
};